package org.example.erat.log.service;

import org.example.erat.log.core.LoggerSingleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 操作日志记录器
 * 用于记录系统关键操作日志
 */
@Service
public class OperationLogger {

    private static final Logger operationLogger = LoggerFactory.getLogger("org.example.erat.operation");
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // 操作日志文件路径
    private static final String LOG_DIR = "logs";
    private static final String OPERATION_LOG_PATH = LOG_DIR + File.separator + "operation.log";

    /**
     * 构造函数
     */
    public OperationLogger() {
        // 确保日志目录存在
        File dir = new File(LOG_DIR);
        if (!dir.exists()) {
            boolean created = dir.mkdirs();
            if (!created) {
                System.err.println("创建日志目录失败: " + LOG_DIR);
            }
        }

        // 写入日志文件头
        try (FileWriter fw = new FileWriter(OPERATION_LOG_PATH, true);
             PrintWriter pw = new PrintWriter(fw)) {

            String timestamp = dateFormat.format(new Date());
            pw.println("\n" + timestamp + " - ========== 系统操作日志 ==========");

        } catch (IOException e) {
            System.err.println("写入日志文件失败: " + e.getMessage());
        }
    }

    /**
     * 记录学生导入操作
     * @param count 导入学生数量
     * @param className 班级名称
     */
    public void logStudentImport(int count, String className) {
        String message = String.format("【学生导入】成功导入 %d 名学生到班级 [%s]", count, className);
        operationLogger.info(message);
        LoggerSingleton.getInstance().info(message);
    }

    /**
     * 记录实验报告分析操作
     * @param experimentName 实验名称
     * @param totalCount 总文件数
     * @param validCount 有效文件数
     * @param className 班级名称
     */
    public void logReportAnalysis(String experimentName, int totalCount, int validCount, String className) {
        String message = String.format("【报告分析】实验 [%s] 报告分析完成，班级 [%s]，共 %d 个文件，有效文件 %d 个",
                experimentName, className, totalCount, validCount);
        operationLogger.info(message);
        LoggerSingleton.getInstance().info(message);
    }

    /**
     * 记录文件名不合规异常
     * @param fileName 文件名
     * @param experimentName 实验名称
     */
    public void logInvalidFileName(String fileName, String experimentName) {
        String message = String.format("【文件名错误】文件名不合规: %s，实验 [%s]", fileName, experimentName);
        operationLogger.warn(message);
        LoggerSingleton.getInstance().warn(message);
    }

    /**
     * 记录学生不在名单中异常
     * @param fileName 文件名
     * @param studentId 学生ID
     * @param studentName 学生姓名
     * @param experimentName 实验名称
     */
    public void logUnknownStudent(String fileName, String studentId, String studentName, String experimentName) {
        String message = String.format("【学生不存在】学号 [%s]，姓名 [%s]，文件 [%s]，实验 [%s]",
                studentId, studentName, fileName, experimentName);
        operationLogger.warn(message);
        LoggerSingleton.getInstance().warn(message);
    }

    /**
     * 记录文件解析异常
     * @param fileName 文件名
     * @param errorMessage 错误信息
     */
    public void logFileParseError(String fileName, String errorMessage) {
        String message = String.format("【文件解析错误】文件 [%s]，错误: %s", fileName, errorMessage);
        operationLogger.error(message);
        LoggerSingleton.getInstance().error(message);
    }

    /**
     * 记录不支持的文件类型异常
     * @param fileName 文件名
     * @param fileType 文件类型
     */
    public void logUnsupportedFileType(String fileName, String fileType) {
        String message = String.format("【不支持的文件类型】类型 [%s]，文件 [%s]，仅支持Excel、Word和CSV格式", fileType, fileName);
        operationLogger.warn(message);
        LoggerSingleton.getInstance().warn(message);
    }

    /**
     * 记录系统启动
     * @param appName 应用名称
     * @param version 版本号
     */
    public void logSystemStartup(String appName, String version) {
        String message = String.format("【系统启动】%s，版本: %s", appName, version);
        operationLogger.info(message);
        LoggerSingleton.getInstance().info(message);
    }

    /**
     * 记录系统关闭
     * @param appName 应用名称
     */
    public void logSystemShutdown(String appName) {
        String message = String.format("【系统关闭】%s", appName);
        operationLogger.info(message);
        LoggerSingleton.getInstance().info(message);
    }

    /**
     * 记录自定义操作日志
     * @param operation 操作名称
     * @param details 详细信息
     */
    public void logOperation(String operation, String details) {
        String message = String.format("【%s】%s", operation, details);
        operationLogger.info(message);
        LoggerSingleton.getInstance().info(message);
    }

    /**
     * 记录批量操作结果
     * @param operation 操作名称
     * @param successCount 成功数量
     * @param failCount 失败数量
     * @param totalCount 总数量
     */
    public void logBatchResult(String operation, int successCount, int failCount, int totalCount) {
        String message = String.format("【批量%s】总数: %d, 成功: %d, 失败: %d",
                operation, totalCount, successCount, failCount);
        operationLogger.info(message);
        LoggerSingleton.getInstance().info(message);
    }

    /**
     * 记录文件扫描开始
     * @param directoryPath 目录路径
     * @param className 班级名称
     * @param courseName 课程名称
     */
    public void logScanStart(String directoryPath, String className, String courseName) {
        String message = String.format("【扫描开始】目录: [%s], 班级: [%s], 课程: [%s]",
                directoryPath, className, courseName);
        operationLogger.info(message);
        LoggerSingleton.getInstance().info(message);
    }

    /**
     * 记录文件扫描完成
     * @param directoryPath 目录路径
     * @param fileCount 文件数量
     * @param validCount 有效文件数量
     * @param invalidCount 无效文件数量
     * @param unknownStudentCount 未知学生数量
     */
    public void logScanComplete(String directoryPath, int fileCount, int validCount,
                               int invalidCount, int unknownStudentCount) {
        String message = String.format("【扫描完成】目录: [%s], 总文件: %d, 有效: %d, 无效: %d, 未知学生: %d",
                directoryPath, fileCount, validCount, invalidCount, unknownStudentCount);
        operationLogger.info(message);
        LoggerSingleton.getInstance().info(message);
    }

    /**
     * 记录文件名格式错误详情
     * @param fileName 文件名
     * @param expectedFormat 期望格式
     */
    public void logFileNameFormatError(String fileName, String expectedFormat) {
        String message = String.format("【文件名格式错误】文件: [%s], 应为: %s", fileName, expectedFormat);
        operationLogger.warn(message);
        LoggerSingleton.getInstance().warn(message);
    }

    /**
     * 记录学生不在名单中详情
     * @param studentId 学生ID
     * @param studentName 学生姓名
     * @param className 班级名称
     */
    public void logStudentNotInClass(String studentId, String studentName, String className) {
        String message = String.format("【学生不在名单】学号: [%s], 姓名: [%s], 班级: [%s]",
                studentId, studentName, className);
        operationLogger.warn(message);
        LoggerSingleton.getInstance().warn(message);
    }
}
